package com.lzy.wzy.service.imp;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lzy.wzy.constant.MyConstant;
import com.lzy.wzy.mapper.UserMapper;
import com.lzy.wzy.mapper.WorkMapper;
import com.lzy.wzy.model.*;
import com.lzy.wzy.result.ResponseCode;
import com.lzy.wzy.result.Result;
import com.lzy.wzy.service.MyFlowableService;
import com.lzy.wzy.service.TemplateService;
import com.lzy.wzy.service.WorkOrderService;
import com.lzy.wzy.token.MyUsernamePasswordToken;
import com.lzy.wzy.utils.PatternUtils;
import com.lzy.wzy.utils.WorkOrderUtils;
import com.lzy.wzy.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.streaming.SXSSFRow;
import org.apache.poi.xssf.streaming.SXSSFSheet;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class WorkOrderServiceImp implements WorkOrderService {
    private final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    @Autowired
    private WorkMapper workMapper;

    @Autowired
    private WorkOrderUtils workOrderUtils;

    @Autowired
    private MyFlowableService myFlowableService;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TemplateService templateService;


    /*
     * @Author wzy
     * @Description //TODO 添加新的工单
     * @Date 2021/8/3 17:53
     * @Param * @param: workOrderBean
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doAddWorkOrder(WorkOrderBean workOrderBean) {
        String serialNumber = workOrderUtils.getSerialNumber(workOrderBean.getWorkType());
        log.info("serialNumber {}", serialNumber);
        String workOrderNumber = workOrderUtils.getWorkOrderNumber(workOrderBean.getWorkType(), serialNumber);
        workOrderBean.setWorkOrderNumber(workOrderNumber);
        workOrderBean.setPlanCreateTime(LocalDate.now());
        if (!verifyWorkPattern(workOrderBean)) {
            return Result.invalidFormat();
        }
        workOrderBean.setProductCode(workOrderBean.getProductCode().trim());
        workOrderBean.setSerialNumber(serialNumber);
        workOrderBean.setStatus(MyConstant.WorkOrderStatus.RELEASE);
        if (workMapper.addWorkOrder(workOrderBean) > 0) {
            return Result.success();
        } else {
            return Result.failure("添加失败");
        }
    }

    private boolean verifyWorkPattern(WorkOrderBean workOrderBean) {
        String workOrderNumber = workOrderBean.getWorkOrderNumber();
        return PatternUtils.checkWorkOrderNumber(workOrderNumber)
                && workMapper.getSingleWorkOrder(workOrderNumber) < 1
                && workOrderUtils.verifyDateFormat(workOrderBean.getPlanBeginTime(), workOrderBean.getPlanEndTime())
                && PatternUtils.verifySoftVersion(workOrderBean.getSoftwareVersion())
                && workOrderUtils.verifyDateFormat(workOrderBean.getPlanCreateTime(), workOrderBean.getPlanBeginTime());
    }


    /*
     * @Author wzy
     * @Description //TODO 查询所有工单
     * @Date 2021/8/3 17:52
     * @Param * @param: pageSize
     * @param: pageNum
     * @return com.lzy.wzy.result.Response<com.github.pagehelper.PageInfo<com.lzy.wzy.vo.WorkOrderVo>>
     **/
    @Override
    public Result<PageInfo<WorkOrderVo>> doQueryAllWorkOrder(Integer pageSize, Integer pageNum) {
        PageHelper.startPage(pageNum, pageSize);

        PageInfo<WorkOrderVo> pageInfo = new PageInfo<>(workMapper.queryAllWorkOrder(MyConstant.WorkOrderStatus.RELEASE));
        return Result.success(pageInfo);
    }


    /*
     * @Author wzy
     * @Description //TODO 搜索框查询工单
     * @Date 2021/8/3 17:52
     * @Param * @param: pageSize
     * @param: pageNum
     * @param: searchValue
     * @return com.lzy.wzy.result.Response<com.github.pagehelper.PageInfo<com.lzy.wzy.vo.WorkOrderVo>>
     **/
    @Override
    public Result<PageInfo<WorkOrderVo>> doSearch(Integer pageSize, Integer pageNum, String searchValue) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<WorkOrderVo> pageInfo = new PageInfo<>(workMapper.search(searchValue));
        return Result.success(pageInfo);
    }


    /*
     * @Author wzy
     * @Description //TODO 根据工单号修改工单
     * @Date 2021/8/3 17:51
     * @Param * @param: workOrderBean
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doModifyWorkOrderByNo(ModifyWorkOrderBean workOrderBean) {
        String workOrderNumber = workOrderBean.getWorkOrderNumber();
        String status = workMapper.getWorkOrderStatus(workOrderNumber);
        LocalDate createTime = workMapper.getWorkOrderCreateTime(workOrderNumber);
        if (!(MyConstant.WorkOrderStatus.CASECLOSE.equals(status) || MyConstant.WorkOrderStatus.FINISHED.equals(status))
                && PatternUtils.checkWorkOrderNumber(workOrderNumber)
                && (workOrderBean.getSoftwareVersion().equals("null") || PatternUtils.verifySoftVersion(workOrderBean.getSoftwareVersion()))
                && workOrderUtils.verifyDateFormat(createTime, workOrderBean.getPlanBeginTime())
                && workOrderUtils.verifyDateFormat(workOrderBean.getPlanBeginTime(), workOrderBean.getPlanEndTime())
                && workMapper.getSingleWorkOrder(workOrderNumber) > 0) {
            //获取工单修改前信息
            ModifyWorkOrderBean updateBefore = workMapper.queryWorkOrderInfoByNO(workOrderNumber);
            if (updateBefore != null && workMapper.modifyWorkOrder(workOrderBean) > 0) {
                workOrderBean.setProductCode(workOrderBean.getProductCode().trim());
                String updateInfo = workOrderUtils.getSingleWorkOrderUpdateInfo(updateBefore, workOrderBean);
                if (workOrderUtils.recordModificationInformation(workOrderBean.getWorkOrderNumber(), updateInfo, 1, 0) > 0) {
                    log.info("修改记录插入成功");
                    return Result.success("修改成功");
                }
            }
        }
        return Result.failure("修改失败");
    }

    /*
     * @Author wzy
     * @Description //TODO 历史时间查询工单
     * @Date 2021/8/3 17:51
     * @Param * @param: pageSize
     * @param: pageNum
     * @param: historicalTime
     * @return com.lzy.wzy.result.Response<com.github.pagehelper.PageInfo<com.lzy.wzy.vo.WorkOrderVo>>
     **/
    @Override
    public Result<PageInfo<WorkOrderVo>> doSearchHistoricalTickets(Integer pageSize, Integer pageNum, String historicalTime) {
        //校验日期格式
        try {
            LocalDate parse = LocalDate.parse(historicalTime);
            historicalTime = parse.format(formatter);
        } catch (Exception e) {
            return Result.invalidFormat();
        }
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<WorkOrderVo> pageInfo = new PageInfo<>(workMapper.searchHistoricalTickets(historicalTime));
        return Result.success(pageInfo);
    }

    /*
     * @Author wzy
     * @Description //TODO 批量修改工单
     * @Date 2021/8/3 17:50
     * @Param * @param: list
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doBatchModifyWorkOrder(List<ModifyWorkOrderBean> workOrderBeans) {
        List<String> workOrderNumbers = new LinkedList<>();
        for (ModifyWorkOrderBean workOrderBean : workOrderBeans) {
            workOrderNumbers.add(workOrderBean.getWorkOrderNumber());
            if (!workOrderUtils.verifyDateFormat(workOrderBean.getPlanBeginTime(), workOrderBean.getPlanEndTime())
                    || !workOrderUtils.verifyDateFormat(workMapper.getWorkOrderCreateTime(workOrderBean.getWorkOrderNumber()), workOrderBean.getPlanBeginTime())) {
                return Result.failure("日期错误");
            }
            if (workOrderBean.getSoftwareVersion().equals("null")) {
                continue;
            }
            if (!PatternUtils.verifySoftVersion(workOrderBean.getSoftwareVersion())) {
                return Result.failure("软件版本格式错误");
            }
        }
        List<String> statusList = workMapper.getMultipleWorkOrderStatus(workOrderNumbers);
        //验证工单软件版本

        if (workOrderUtils.verifyAllWorkOrderNumber(statusList)) {
            return Result.failure("修改失败，请检查工单状态");
        }
        List<ModifyWorkOrderBean> multipleWorkOrderInfo = workMapper.getMultipleWorkOrderInfo(workOrderNumbers);


        Map<String, String> modificationRecord = workOrderUtils.getMultipleModificationRecord(multipleWorkOrderInfo, workOrderBeans);

        List<ModifyWorkOrderBean> updateAfterBeans = workOrderBeans.stream().filter((ModifyWorkOrderBean m) -> modificationRecord.containsKey(m.getWorkOrderNumber())).collect(Collectors.toList());

        if (modificationRecord.size() > 0) {
            workMapper.batchUpdateWorkOrder(updateAfterBeans);
            MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
            String userUuid = (String) token.getPrincipal();
            workMapper.batchInsertMultipleModifyInfo(modificationRecord, LocalDateTime.now(), userUuid, 1, 0);
            return Result.success();
        }
        return Result.failure("请填写数据");
    }

    /*
     * @Author wzy
     * @Description //TODO 通过工单状态查询工单所有信息
     * @Date 2021/8/3 17:49
     * @Param * @param: pageSize
     * @param: pageNum
     * @param: status
     * @return com.lzy.wzy.result.Response<com.github.pagehelper.PageInfo<com.lzy.wzy.vo.WorkOrderVo>>
     **/
    @Override
    public Result<PageInfo<WorkOrderVo>> doQueryWorkOrdersThroughWorkOrderStatus(Integer pageSize, Integer pageNum, String status) {
        PageHelper.startPage(pageNum, pageSize);
        List<WorkOrderVo> w1 = workMapper.getWorkOrderByStatus(status);
        if (MyConstant.WorkOrderStatus.InSystem.equals(status)) {
            List<WorkOrderVo> w2 = workMapper.getWorkOrderByStatus(MyConstant.WorkOrderStatus.EXCEPTION);
            w1.addAll(w2);
        }
        PageInfo<WorkOrderVo> pageInfo = new PageInfo<>(w1);
        return Result.success(pageInfo);
    }


    /*
     * @Author wzy
     * @Description //TODO 工单结案
     * @Date 2021/8/23 9:03
     * @Param * @param: workOrderNumber
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doWorkOrderSettlement(String workOrderNumber) {
        IdentifierStatus identifierStatus = workMapper.getIdentifierAndStatus(workOrderNumber);
        if (identifierStatus.getIdentifier() != 1) {
            return Result.failure("不可结案");
        }
        if (updateStatus(MyConstant.WorkOrderStatus.FINISHED, MyConstant.WorkOrderStatus.CASECLOSE, identifierStatus.getStatus(), workOrderNumber)) {
            workMapper.updateClosingTime(LocalDate.now(), workOrderNumber);

            return Result.success();
        }
        return Result.failure();
    }

    private boolean updateStatus(String expectedStatus, String futureStatus, String workStatus, String workOrderNumber) {
        return expectedStatus.equals(workStatus)
                && workMapper.updateWorkOrderIdentifierAndStatus(1, futureStatus, workOrderNumber) > 0;
    }

    /*
     * @Author wzy
     * @Description //TODO 工单反结案
     * @Date 2021/8/23 9:03
     * @Param * @param: workOrderNumber
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> reserveWorkOrder(String workOrderNumber) {
        LocalDate completionTime = workMapper.getCompletionTimeByNumber(workOrderNumber);
        if (LocalDate.now().isAfter(completionTime.plusMonths(1))) {
            return Result.failure("反转时间已过");
        }
        String status = workMapper.getWorkOrderStatus(workOrderNumber);
        if (updateStatus(MyConstant.WorkOrderStatus.CASECLOSE, MyConstant.WorkOrderStatus.FINISHED, status, workOrderNumber)) {
            workMapper.saveAntiClosingTime(LocalDate.now(), workOrderNumber);
            workOrderUtils.saveBulletin("反结案:", workOrderNumber, "审核错误");
            return Result.success();
        }
        return Result.failure();
    }

    /*
     * @Author wzy
     * @Description //TODO 反完工
     * @Date 2021/8/23 9:03
     * @Param * @param: workOrderNumber
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doAntiFinishedWorkOrder(String workOrderNumber) {
        LocalDate completionTime = workMapper.getCompletionTimeByNumber(workOrderNumber);
        if (LocalDate.now().isAfter(completionTime.plusMonths(1))) {
            return Result.failure("反转时间已过");
        }
        IdentifierStatus identifierStatus = workMapper.getIdentifierAndStatus(workOrderNumber);
        if (identifierStatus.getIdentifier() != 1) {
            return Result.failure("不可反转");
        }
        String status = identifierStatus.getStatus();
        if (updateStatus(MyConstant.WorkOrderStatus.FINISHED, MyConstant.WorkOrderStatus.InSystem, status, workOrderNumber)) {
            workOrderUtils.saveBulletin("反完工:", workOrderNumber, "审核错误");
            return Result.success();
        }
        return Result.failure();
    }


    /*
     * @Author wzy
     * @Description //TODO 获取半年审批结果
     * @Date 2021/8/23 9:05
     * @Param * @param: pageNum
     * @param: pageSize
     * @return com.lzy.wzy.result.Response<com.github.pagehelper.PageInfo<com.lzy.wzy.vo.ApprovalResultsVo>>
     **/
    @Override
    public Result<PageInfo<ApprovalResultsVo>> doObtainTheApprovalResultsWithinHalfAYear(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        String userId = (String) token.getPrincipal();
        List<ApprovalResultsVo> results = userMapper.getWithinHalfAYearAllApprovalResults(userId);
        for (ApprovalResultsVo resultsVo : results) {
            if (null == resultsVo.getExecutor()) {
                resultsVo.setExecutor("未审核");
            }
        }
        PageInfo<ApprovalResultsVo> pageInfo = new PageInfo<>(results);
        return Result.success(pageInfo);
    }

    /*
     * @Author wzy
     * @Description //TODO 获取审批详情
     * @Date 2021/8/23 9:05
     * @Param * @param: id
     * @return com.lzy.wzy.result.Response<com.lzy.wzy.vo.ApprovalDetailsVo>
     **/
    @Override
    public Result<ApprovalDetailsVo> doGetApprovalDetails(int id) {
        ApprovalDetailsVo details = userMapper.getApprovalDetails(id);
//        String status = details.getStatus();
//        if (MyConstant.ApproveStatus.EXAMINATION_PASSED.equals(status)
//                || MyConstant.ApproveStatus.END_OF_REVIEW.equals(status)) {
//            details.setRejectReason(MyConstant.ApproveStatus.EXAMINATION_PASSED);
//        } else if (MyConstant.ApproveStatus.UNDER_REVIEW.equals(status)) {
//            details.setRejectReason(MyConstant.ApproveStatus.MODERATED);
//        } else if (MyConstant.ApproveStatus.MODERATED.equals(details.getStatus())) {
//            details.setRejectReason(MyConstant.ApproveStatus.MODERATED);
//        }
        return Result.success(details);
    }

    /*
     * @Author wzy
     * @Description //TODO 获取待处理异常
     * @Date 2021/8/23 9:05
     * @Param * @param: workOrderNumber
     * @return com.lzy.wzy.result.Response<java.util.List<com.lzy.wzy.vo.PendingExceptionInfoVo>>
     **/
    @Override
    public Result<List<PendingExceptionInfoVo>> doGetAllPendingExceptionInfo(String workOrderNumber) {
        return Result.success(workMapper.getPendingExceptionInfo(workOrderNumber, MyConstant.ReportStatus.PENDING));
    }

    /*
     * @Author wzy
     * @Description //TODO
     * @Date 2021/8/23 9:05
     * @Param * @param: workOrderNumber
     * @param: status
     * @return com.lzy.wzy.result.Response<java.util.List<com.lzy.wzy.vo.ConfirmedExceptionInfoVo>>
     **/
    @Override
    public Result<List<ConfirmedExceptionInfoVo>> doGetAllExceptionInfoByStatus(String workOrderNumber, String status) {
        return Result.success(workMapper.getAllExceptionInfoByStatus(workOrderNumber, status));
    }


    /*
     * @Author wzy
     * @Description //TODO 异常处理，方案提交
     * @Date 2021/8/23 9:06
     * @Param * @param: id
     * @param: program
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doExceptionWorkOrderHandling(int id, String program, MultipartFile file, String workOrderNumber) throws Exception {
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        List<String> list = token.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        int identifier = workMapper.getTransferIdentifierById(id);
        if (!(Arrays.stream(MyConstant.ApproveGroup.craft).anyMatch(list::contains) && list.contains(MyConstant.ApproveGroup.quality))) {
            if (identifier == 0) {
                if (Arrays.stream(MyConstant.ApproveGroup.craft).anyMatch(list::contains)) {
                    return Result.failure("等待质量处理, 提交失败");
                }
            } else {
                if (list.contains(MyConstant.ApproveGroup.quality)) {
                    return Result.failure("已委托给工艺部,提交失败");
                }
            }
        }
        String path = null;
        if (file != null) {
            String name = file.getOriginalFilename();
            assert name != null;
            String suffix = name.substring(name.lastIndexOf("."));
            String fileName = UUID.randomUUID().toString().replace("-", "") + suffix;
            File file1 = new File("/usr/local/run/file/" + fileName);
            path = file1.getPath();
            file.transferTo(file1);
        }
        String status = workMapper.getStatusByExceptionId(id);
        if (MyConstant.ReportStatus.PENDING.equals(status)) {
            String userId = (String) token.getPrincipal();
            if (workMapper.saveTreatmentPlan(program.trim(), id, userId, LocalDateTime.now(), MyConstant.ReportStatus.PENDING_EXECUTE, path) > 0) {
                return Result.success("处理成功");
            }
        }
        return Result.failure("处理失败");
    }

    /*
     * @Author wzy
     * @Description //TODO 生产执行方案
     * @Date 2021/8/23 9:07
     * @Param * @param: id
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doExecutionConfirmation(int id, String exeResult) {
        String status = workMapper.getStatusByExceptionId(id);
        if (MyConstant.ReportStatus.PENDING_EXECUTE.equals(status)) {
            MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
            String userId = (String) token.getPrincipal();
            if (workMapper.saveExecutorInfo(userId, LocalDateTime.now(), exeResult.trim(), MyConstant.ReportStatus.TOBE_CONFIRMED, id) > 0) {
                return Result.success("执行成功");
            }
        }
        return Result.failure("执行失败");
    }

    /*
     * @Author wzy
     * @Description //TODO 最终确认异常结束
     * @Date 2021/8/23 9:07
     * @Param * @param: id
     * @param: workOrderNumber
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doFinalConfirmation(int id, String workOrderNumber) {
        String status = workMapper.getStatusByExceptionId(id);
        if (MyConstant.ReportStatus.TOBE_CONFIRMED.equals(status)) {
            MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
            String userId = (String) token.getPrincipal();
            if (workMapper.saveConfirmorInformation(userId, LocalDateTime.now(), MyConstant.ReportStatus.FINISHED, id) > 0) {
                if (workMapper.getThisWorkOrderExceptionCount(workOrderNumber, MyConstant.ReportStatus.FINISHED) == 0) {
                    String workOrderStatus = workMapper.getExceptionWorkOrderStatus(workOrderNumber);
                    if (workOrderStatus != null) {
                        workMapper.updateWorkOrderStatus(workOrderStatus, workOrderNumber);
                    }
                }
                return Result.success("执行成功");
            }
        }
        return Result.failure("执行失败");
    }

    /*
     * @Author wzy
     * @Description //TODO 获取所有已经处理完结异常
     * @Date 2021/8/23 9:08
     * @Param * @param: workOrderNumber
     * @return com.lzy.wzy.result.Response<java.util.List<com.lzy.wzy.vo.HistoryExceptionVo>>
     **/
    @Override
    public Result<List<HistoryExceptionVo>> doGetAllConfirmedExceptionInformation(String workOrderNumber) {
        return Result.success(workMapper.getThisWorkOrderAllExceptionInfo(workOrderNumber, MyConstant.ReportStatus.FINISHED));
    }

    /*
     * @Author wzy
     * @Description //TODO 查询异常信息
     * @Date 2021/8/23 9:08
     * @Param * @param: searchValue
     * @return com.lzy.wzy.result.Response<java.util.List<com.lzy.wzy.vo.HistoryExceptionVo>>
     **/
    @Override
    public Result<List<HistoryExceptionVo>> doExceptionInformationQuery(String searchValue) {
        return Result.success(workMapper.getExceptionInfoByCondition(searchValue));
    }


    /*
     * @Author wzy
     * @Description //TODO 删除工单
     * @Date 2021/8/23 9:08
     * @Param * @param: workOrderNumber
     * @return com.lzy.wzy.result.Response<org.apache.poi.ss.formula.functions.T>
     **/
    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doDeleteWorkOrder(String workOrderNumber) {
        String status = workMapper.getWorkOrderStatus(workOrderNumber);
        if (MyConstant.WorkOrderStatus.RELEASE.equals(status)
                && workMapper.deleteWorkOrder(workOrderNumber) > 0) {
            //删除记录表操作信息
            workMapper.deleteModifyRecordByNumber(workOrderNumber);

            workMapper.deleteReportExceptionInfoByNumber(workOrderNumber);

            return Result.success("删除成功");
        }
        return Result.failure("删除失败");
    }


    @Override
    public Result<IndexVo> doInit() {
        IndexVo indexVo = new IndexVo();
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        String userId = (String) token.getPrincipal();
//        //TODO 下发待处理异常任务
//        indexVo.setExceptionWorkOrders(getTheAbnormalTicketNumber(token));
        //TODO 获取历史任务
        indexVo.setTasks(myFlowableService.doGetAnAgentTask(userId,0,5));

        indexVo.setTaskVos(userMapper.getTask(userId));

//        //TODO 获取工单信息统计
//        indexVo.setWorkStatistics(getWorkOrderStatistics());
        //TODO 下发数据统计初始化信息
        YearMonthVo timeVisit = getTimeVisit();
        indexVo.setTimes(timeVisit);
        List<EchartsVo> echartsVos;
        if (timeVisit!=null) {
            echartsVos=templateService.doStatisticsOfFinishedMachines(timeVisit.getDefaultYear(),timeVisit.getDefaultMonth(),timeVisit.getDefaultDay(),timeVisit.getDefaultProductCode()).getData();
            indexVo.setTimes(timeVisit);
        }else {
            echartsVos=doGetEmpty();
        }
        indexVo.setEchartsVos(echartsVos);
        //TODO 获取审批结果
       // indexVo.setResultsVos(getApprovalResult(userId));
        //indexVo.setBulletins(workMapper.getBulletin());
        return Result.success(indexVo);
    }

    private List<EchartsVo> doGetEmpty() {
        Integer totalQuantity = workMapper.getTotalQuantity();
        if (totalQuantity == null) {
            totalQuantity = 0;
        }
        Integer finalTotalQuantity = totalQuantity;
        List<String> names = new ArrayList<String>() {{
            add("在制：0台(0%)");
            add("完工：0台(0%)");
            add("入库：0台(0%)");
            add("待生产：" + finalTotalQuantity + "台(100%)");
            add("总在制：0台(0%)");
            add("总完工：0台(0%)");
            add("总入库：0台(0%)");
        }};
        List<EchartsVo> list = new ArrayList<>();
        EchartsVo echartsVo;
        for (String name : names) {
            echartsVo = new EchartsVo();
            echartsVo.setValue(0);
            echartsVo.setName(name);
            list.add(echartsVo);
        }
        return list;
    }

    @Override
    public Result<List<ApprovalResultsVo>> doGetApprovalResult() {
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        String userId = (String) token.getPrincipal();
        return Result.success(getApprovalResult(userId));
    }


    @Override
    public void doDownloadAttachments(HttpServletResponse response, int id, int idf) throws IOException {
        String path;
        if (idf == 2) {
            path = workMapper.getDixPathById(id);
        } else if (idf == 1) {
            path = workMapper.getReportFilePathById(id);
        } else {
            return;
        }
        if (StringUtils.isBlank(path)) {
            log.info("找不到附件");
            return;
        }
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(path), StandardCharsets.ISO_8859_1));

        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(response.getOutputStream(), StandardCharsets.ISO_8859_1));
        // BufferedInputStream inputStream = new BufferedInputStream();
//        // 设置头信息
//        response.addHeader("Content-Disposition", "attachment;filename=" + path.substring(path.lastIndexOf("\\")));
//        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(path, "UTF-8"));
//        //response.setCharacterEncoding("UTF-8");
//        response.setContentType("application/vnd.ms-excel;charset=UTF-8");

        char[] chars = new char[1024];
        int len;
        while ((len = bufferedReader.read(chars)) != -1) {
            bufferedWriter.write(chars, 0, len);
        }
        bufferedWriter.flush();
        bufferedWriter.close();
        bufferedReader.close();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doTransfer(int id) {
        if (workMapper.getTransferIdentifierById(id) == 1) {
            return Result.failure("已转交至工艺，请勿重复转让");
        } else {
            workMapper.updateTransferIdentifierByIdAndStatus(1, id, MyConstant.ReportStatus.PENDING);
            return Result.success("成功转让");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doReportAMajorException(String workOrderNumber,int id) {
        String status = workMapper.getWorkOrderStatus(workOrderNumber);
        if (MyConstant.WorkOrderStatus.EXCEPTION.equals(status)) {
            if (workMapper.updateWorkOrderStatus(MyConstant.WorkOrderStatus.MAJOR_EXCEPTION, workOrderNumber) > 0) {

                return Result.success();
            }
        }
        return Result.failure("上报失败");
    }

    @Override
    public Result<String> doGetFileSuffix(int id, int idf) {
        String path = null;
        if (idf == 2) {
            path = workMapper.getDixPathById(id);
        } else if (idf == 1) {
            path = workMapper.getReportFilePathById(id);
        }
        if (path == null) {
            return Result.failure("没有可下载的附件");
        }
        String suffix = path.substring(path.lastIndexOf("."));
        return Result.to(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMsg(), suffix);
    }

    @Override
    public Result<List<ApproveSignVo>> doObtainTheSignatureOfTheApprover(String workOrderNumber) {
        return Result.success(workMapper.getApproveSign(workOrderNumber));
    }

    @Override
    public Result<List<String>> doObtainAllOutstandingWorkOrderNumbers() {
        return Result.success(workMapper.getAllWorkOrderNumber());
    }

    @Override
    public Result<WorkOrderPartInfo> doObtainPartOfWorkOrderInformation(String workOrderNumber) {
        return Result.success(workMapper.obtainPartOfWorkOrderInformation(workOrderNumber));
    }

    @Override
    public Result<List<KeyValueVo>> doGetAllProjectNumber() {
        return Result.success(workMapper.getAllProjectNumber());
    }

    @Override
    public Result<String> doGetProjectInfo(String projectNumber) {
        return Result.to(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMsg(), workMapper.queryProjectName(projectNumber));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doSaveProjectInfo(OutOfHoursStatisticsBean outOfHoursStatisticsBean) {
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        String userId=(String) token.getPrincipal();
        outOfHoursStatisticsBean.setName(userId);
        String projectNumber = outOfHoursStatisticsBean.getProjectNumber();
        LocalDate projectDate = workMapper.getProjectDate(projectNumber);
        LocalDate now = outOfHoursStatisticsBean.getProjectDate();
        if (projectDate != null && (now.isBefore(projectDate) && now.isBefore(projectDate.minusDays(2)))) {
            return Result.failure("非法日期，项目创建时间为:" + projectDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        outOfHoursStatisticsBean.setProjectNumber(projectNumber.trim());
        outOfHoursStatisticsBean.setProjectName(outOfHoursStatisticsBean.getProjectName().trim());
        outOfHoursStatisticsBean.setYear(now.getYear());
        outOfHoursStatisticsBean.setMonth(now.getMonthValue());
        if (workMapper.queryProjectExist(projectNumber, now,userId) > 0) {
            if (workMapper.updateProjectInfo(outOfHoursStatisticsBean) > 0) {
                return Result.success("更新成功");
            } else {
                return Result.failure("更新失败");
            }
        } else {
            if (workMapper.saveProjectInfo(outOfHoursStatisticsBean) > 0) {
                return Result.success("保存成功");
            }
            return Result.failure("保存失败");
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doSaveAttTime(ProductionManagementHoursBean productionManagementHoursBean) {
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        String username = (String) token.getCredentials();
        if (username != null && !username.equalsIgnoreCase(productionManagementHoursBean.getJobNumber())) {
            return Result.failure("请勿使用他人工号");
        }
        LocalDate projectDate = workMapper.getProjectDate(productionManagementHoursBean.getProjectNumber());
        LocalDate recordDate = productionManagementHoursBean.getRecordDate();
        if (projectDate != null && (recordDate.isBefore(projectDate) && recordDate.isBefore(projectDate.minusDays(2)))) {
            return Result.failure("非法日期，项目创建时间为:" + projectDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        }
        productionManagementHoursBean.setYear(recordDate.getYear());
        productionManagementHoursBean.setMonth(recordDate.getMonthValue());
        if (workMapper.queryManageWorkingHoursCount(username, productionManagementHoursBean.getProjectNumber(), recordDate) > 0) {
            if (workMapper.updateAttTimeInfo(productionManagementHoursBean) > 0) {
                return Result.success("更新成功");
            } else {
                return Result.failure("更新失败");
            }
        } else {
            if (workMapper.saveAttTime(productionManagementHoursBean) > 0) {
                return Result.success("保存成功");
            }
            return Result.failure("保存失败");
        }
    }

    @Override
    public Result<PageInfo<WorkingHoursVo>> doObtainProductionTimeInformation(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<WorkingHoursVo> pageInfo = new PageInfo<>(workMapper.getAllProductionHoursInfo());
        return Result.success(pageInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doSaveProductionTimeInformation(WorkingHoursVo workingHoursVo) {
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        String userId=(String) token.getPrincipal();
        workingHoursVo.setName(userId);
        LocalDate recordDate = workingHoursVo.getRecordDate();
        String workOrderNumber = workingHoursVo.getWorkOrderNumber();
        LocalDate createTime = workMapper.getWorkOrderCreateTime(workOrderNumber);
        if (createTime != null && recordDate.isBefore(createTime)) {
            return Result.failure("日期选择错误");
        }
        int actualOutput = workingHoursVo.getActualOutput();
        Integer quantity = workMapper.getProductQuantityByWorkOrderNumber(workOrderNumber);
        if (actualOutput > quantity) {
            return Result.failure("实际产出个数错误");
        }
        if (workMapper.checkExistProductionHours(workOrderNumber, recordDate,userId) > 0) {
            WorkingHoursPartBean workingHoursPartBean = new WorkingHoursPartBean();
            BeanUtils.copyProperties(workingHoursVo, workingHoursPartBean);
            workingHoursPartBean.setYear(recordDate.getYear());
            workingHoursPartBean.setMonth(recordDate.getMonthValue());
            if (workMapper.updateProductionHoursInfo(workingHoursPartBean) > 0) {
                return Result.success("更新成功");
            } else {
                return Result.failure("更新成功");
            }
        }
        WorkingHoursBean workingHoursBean = new WorkingHoursBean();
        BeanUtils.copyProperties(workingHoursVo, workingHoursBean);
        workingHoursBean.setYear(recordDate.getYear());
        workingHoursBean.setMonth(recordDate.getMonthValue());
        if (workMapper.saveProductionHoursInfo(workingHoursBean) > 0) {
            return Result.success("保存成功");
        }
        return Result.failure("保存失败");
    }


    @Override
    public Result<PageInfo<WorkingHoursVo>> doQueryHoursByWorkNumber(String workOrderNumber, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<WorkingHoursVo> pageInfo = new PageInfo<>(workMapper.getProductionHoursInfoByNumber(workOrderNumber));
        return Result.success(pageInfo);
    }

    @Override
    public Result<PageInfo<OutOfHoursStatisticsVo>> doObtainTimeInformationOfAllProjects(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<OutOfHoursStatisticsVo> pageInfo = new PageInfo<>(workMapper.getAllProjectHoursInfo());
        return Result.success(pageInfo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doMonthlyStatisticsOfProductionHours(int year, int month) {
        List<StatHoursVo> statHoursVos = workMapper.statWorkOrderHoursByMonth(year, month);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "工单月报统计", "日", resultVo, true);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doYearStatisticsOfProductionHours(int year) {
        List<StatHoursVo> statHoursVos = workMapper.statWorkOrderHoursByYear(year);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "工单年报统计", "月", resultVo, false);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doWorkOrderNumberMonthStatisticsOfProductionHours(String workOrderNumber, int year, int month) {
        List<StatHoursVo> statHoursVos = workMapper.statMonthWorkOrderHoursByNumber(workOrderNumber, year, month);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "工单月报统计", "日", resultVo, true);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doWorkOrderNumberYearStatisticsOfProductionHours(String workOrderNumber, int year) {
        List<StatHoursVo> statHoursVos = workMapper.statYearWorkOrderHoursByNumber(workOrderNumber, year);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "工单年报统计", "月", resultVo, false);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doMonthlyStatisticsOfProjectHours(int year, int month) {
        List<StatHoursVo> statHoursVos = workMapper.statProjectWorkingHoursByMonth(year, month);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "项目月报统计", "日", resultVo, true);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doYearStatisticsOfProjectHours(int year) {
        List<StatHoursVo> statHoursVos = workMapper.statProjectWorkingHoursByYear(year);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "项目年报统计", "月", resultVo, false);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doProjectNumberMonthStatisticsOfProjectHours(String projectNumber, int year, int month) {
        List<StatHoursVo> statHoursVos = workMapper.statProjectMonthWorkingHoursByProjectNumber(projectNumber, year, month);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "项目月报统计", "日", resultVo, true);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doProjectNumberYearStatisticsOfProjectHours(String projectNumber, int year) {
        List<StatHoursVo> statHoursVos = workMapper.statProjectYearWorkingHoursByProjectNumber(projectNumber, year);
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        packSvo(statHoursVos, "项目年报统计", "月", resultVo, false);
        return Result.success(resultVo);
    }

    @Override
    public Result<PageInfo<OutOfHoursStatisticsVo>> doQueryProjectInformationByProjectNumberOrProjectName(String searchValue, int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<OutOfHoursStatisticsVo> pageInfo = new PageInfo<>(workMapper.getProjectHoursInfoByNumberOrName(searchValue.trim()));
        return Result.success(pageInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public Result<T> doAddProject(String projectNumber, String projectName) {
        if (workMapper.addProject(projectNumber.trim(), projectName.trim(), LocalDate.now()) > 0) {
            return Result.success("添加成功");
        }
        return Result.failure("添加失败");
    }

    @Transactional(rollbackFor = Exception.class)

    @Override
    public Result<T> doDeleteProject(String projectNumber) {
        if (workMapper.delProject(projectNumber) > 0) {
            return Result.success("删除成功");
        }
        return Result.failure("删除失败");
    }

    @Override
    public Result<String> doGetProjectInfoByProjectNumber(String projectNumber) {
        String projectName = workMapper.queryProjectName(projectNumber);
        if (projectName != null) {
            return Result.to(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMsg(), projectName);
        }
        return Result.failure("项目不存在");
    }

    @Override
    public Result<StatisticsHoursResultVo> doManageTimeStatisticsByMonth(int year, int month, int idf) {
        String title;
        List<StatHoursVo> statHoursVos;
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        switch (idf) {
            case 0:
                MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
                String username = (String) token.getCredentials();
                statHoursVos = workMapper.getManageMonthWorkingTime(username, year, month);
                title = "个人管理工时月报统计";
                break;
            case 1:
                statHoursVos = workMapper.getAllThePeopleManageMonthWorkingTime(year, month);
                title = "所有人管理工时月报统计";
                break;
            default:
                throw new RuntimeException("请勿篡改数据");
        }

        packSvo(statHoursVos, title, "日", resultVo, true);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doManageTimeStatisticsByYear(int year, int idf) {
        String title;
        List<StatHoursVo> statHoursVos;
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        switch (idf) {
            case 0:
                MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
                String username = (String) token.getCredentials();
                statHoursVos = workMapper.getManageYearWorkingTime(username, year);
                title = "个人管理工时年报统计";
                break;
            case 1:
                statHoursVos = workMapper.getAllThePeopleManageYearWorkingTime(year);
                title = "所有人管理工时年报统计";
                break;
            default:
                throw new RuntimeException("请勿篡改数据");
        }
        packSvo(statHoursVos, title, "月", resultVo, false);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doMonthlyManagementTimeStatisticsByNumber(String projectNumber, int year, int month, int idf) {
        String title;
        List<StatHoursVo> statHoursVos;
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        switch (idf) {
            case 0:
                MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
                String username = (String) token.getCredentials();
                statHoursVos = workMapper.getManageMonthWorkingTimeByProjectNumber(username, year, month, projectNumber);
                title = "项目个人管理工时月报统计";
                break;
            case 1:
                statHoursVos = workMapper.getAllThePeopleManageMonthWorkingTimeByProjectNumber(year, month, projectNumber);
                title = "所有人管理工时月报统计";
                break;
            default:
                throw new RuntimeException("请勿篡改数据");
        }
        packSvo(statHoursVos, title, "日", resultVo, true);
        return Result.success(resultVo);
    }

    @Override
    public Result<StatisticsHoursResultVo> doYearManagementTimeStatisticsByNumber(String projectNumber, int year, int idf) {
        String title;
        List<StatHoursVo> statHoursVos;
        StatisticsHoursResultVo resultVo = new StatisticsHoursResultVo();
        switch (idf) {
            case 0:
                MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
                String username = (String) token.getCredentials();
                statHoursVos = workMapper.getManageYearWorkingTimeByProjectNumber(username, year, projectNumber);
                title = "项目个人管理工时年报统计";
                break;
            case 1:
                statHoursVos = workMapper.getAllThePeopleManageYearWorkingTimeByProjectNumber(year, projectNumber);
                title = "所有人管理工时年报统计";
                break;
            default:
                throw new RuntimeException("请勿篡改数据");
        }
        packSvo(statHoursVos, title, "月", resultVo, false);
        return Result.success(resultVo);
    }

    @Override
    public void doAllThePeopleManagementTimeReport(int idf, int year, int month, HttpServletResponse response) throws IOException {
        List<ManageTimeVo> list;
        String title;
        switch (idf) {
            case 0:
                list = workMapper.getAllThePeopleYearManageWorkingTimeReport(year);
                title = "管理工时年报";
                break;
            case 1:
                list = workMapper.getAllThePeopleMonthManageWorkingTimeReport(year, month);
                title = "管理工时月报";
                break;
            default:
                throw new RuntimeException("请勿篡改数据");
        }

        if (list.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<ManageTimeVo>> collect = list.stream().collect(Collectors.groupingBy(ManageTimeVo::getProjectName));
        Map<String, List<ManageTimeVo>> names = list.stream().collect(Collectors.groupingBy(ManageTimeVo::getName));
        export(title, collect, names, response);
    }

    @Override
    public void doPersonalManagementTimeReport(int idf, int year, int month, HttpServletResponse response) throws IOException {
        List<ManageTimeVo> list;
        String title;
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        String jobNumber = (String) token.getCredentials();
        switch (idf) {
            case 0:
                list = workMapper.getPersonalYearManageWorkingTime(jobNumber, year);
                title = "个人管理工时年报";
                break;
            case 1:
                list = workMapper.getPersonalMonthManageWorkingTime(jobNumber, year, month);
                title = "个人管理工时月报";
                break;
            default:
                throw new RuntimeException("请勿篡改数据");
        }
        if (list.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<ManageTimeVo>> collect = list.stream().collect(Collectors.groupingBy(ManageTimeVo::getProjectName));
        Map<String, List<ManageTimeVo>> names = list.stream().collect(Collectors.groupingBy(ManageTimeVo::getName));
        export(title, collect, names, response);
    }

    @Override
    public Result<PageInfo<ManageWorkingTimeVo>> doQueryAllManagementTimeInformationOfAnIndividual(int pageNum, int pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
        PageInfo<ManageWorkingTimeVo> pageInfo = new PageInfo<>(workMapper.getPersonalManageWorkingHoursInfoByJobNumber(String.valueOf(token.getCredentials())));
        return Result.success(pageInfo);
    }

    @Override
    public Result<PageInfo<ManageWorkingTimeVo>> doQueryAllManagementTimeInformationOfAnIndividualByProjectNumber(int pageNum, int pageSize, String projectNumber, String jobNumber) {
        PageHelper.startPage(pageNum, pageSize);
        if (StringUtils.isBlank(jobNumber)) {
            MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
            jobNumber = String.valueOf(token.getCredentials());
        }
        PageInfo<ManageWorkingTimeVo> pageInfo = new PageInfo<>(workMapper.getPersonalManageWorkingHoursInfoByJobNumberAndPNumber(jobNumber, projectNumber));
        return Result.success(pageInfo);
    }

    @Override
    public Result<PageInfo<ManageWorkingTimeVo>> doQueryAllManagementTimeInformationOfAnIndividualByJobNumber(int pageNum, int pageSize, String jobNumber) {
        PageHelper.startPage(pageNum, pageSize);
        PageInfo<ManageWorkingTimeVo> pageInfo = new PageInfo<>(workMapper.getPersonalManageWorkingHoursInfoByJobNumber(jobNumber));
        return Result.success(pageInfo);
    }

    @Override
    public void doExportOfAnnualProductionHours(int year, HttpServletResponse response) throws IOException {
        List<WorkingHoursVo> workingHoursVos = workMapper.queryTheProductionTimeOfThisYear(year);
        if (workingHoursVos.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<WorkingHoursVo>> collect = workingHoursVos.stream().collect(Collectors.groupingBy(WorkingHoursVo::getWorkOrderNumber));
        exportProductionHours(collect, "生产工时年报", response);
    }

    @Override
    public void doExportOfMonthlyProductionHours(int year, int month, HttpServletResponse response) throws IOException {
        List<WorkingHoursVo> workingHoursVos = workMapper.queryTheProductionTimeOfThisMonth(year, month);
        if (workingHoursVos.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<WorkingHoursVo>> collect = workingHoursVos.stream().collect(Collectors.groupingBy(WorkingHoursVo::getWorkOrderNumber));
        exportProductionHours(collect, "生产工时月报", response);
    }


    @Override
    public void doExportOfAnnualProjectHours(int year, HttpServletResponse response) throws IOException {
        List<OutOfHoursStatisticsVo> statisticsVos = workMapper.queryTheProjectTimeOfThisYear(year);
        if (statisticsVos.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<OutOfHoursStatisticsVo>> collect = statisticsVos.stream().collect(Collectors.groupingBy(OutOfHoursStatisticsVo::getProjectNumber));
        exportProjectHours(collect, "项目工时年报", response);
    }

    @Override
    public void doExportOfMonthlyProjectHours(int year, int month, HttpServletResponse response) throws IOException {
        List<OutOfHoursStatisticsVo> statisticsVos = workMapper.queryTheProjectTimeOfThisMonth(year, month);
        if (statisticsVos.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<OutOfHoursStatisticsVo>> collect = statisticsVos.stream().collect(Collectors.groupingBy(OutOfHoursStatisticsVo::getProjectNumber));
        exportProjectHours(collect, "项目工时月报", response);
    }

    @Override
    public void doExportPersonalOfAnnualManagementHours(int year, String jobNumber, HttpServletResponse response) throws IOException {
        if ("EDG".equals(jobNumber)) {
            MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
            jobNumber = String.valueOf(token.getCredentials());
        }
        List<ManageWorkingTimeVo> manageWorkingHoursInfo = workMapper.getPersonalAnnualManageWorkingHoursInfo(year, jobNumber);
        if (manageWorkingHoursInfo.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<ManageWorkingTimeVo>> collect = manageWorkingHoursInfo.stream().collect(Collectors.groupingBy(ManageWorkingTimeVo::getProjectNumber));
        exportManageHours(collect, "管理工时年报", response);
    }


    @Override
    public void doExportPersonalOfMonthlyManagementHours(int year, int month, String jobNumber, HttpServletResponse response) throws IOException {
        if ("EDG".equals(jobNumber)) {
            MyUsernamePasswordToken token = (MyUsernamePasswordToken) SecurityContextHolder.getContext().getAuthentication();
            jobNumber = String.valueOf(token.getCredentials());
        }
        List<ManageWorkingTimeVo> manageWorkingHoursInfo = workMapper.getPersonalMonthlyManageWorkingHoursInfo(year, month, jobNumber);
        if (manageWorkingHoursInfo.isEmpty()) {
            throw new RuntimeException("没有可导出的数据");
        }
        Map<String, List<ManageWorkingTimeVo>> collect = manageWorkingHoursInfo.stream().collect(Collectors.groupingBy(ManageWorkingTimeVo::getProjectNumber));
        exportManageHours(collect, "管理工时月报", response);
    }

    @Override
    public Result<T> doAccordingToDeleteProductionHours(int id) {
        if (workMapper.delProductionHoursById(id) > 0) {
            return Result.success("删除成功");
        }
        return Result.failure("删除失败");
    }

    @Override
    public Result<T> doAccordingToDeleteNonProductionHours(int id) {
        if (workMapper.delProjectHoursById(id) > 0) {
            return Result.success("删除成功");
        }
        return Result.failure("删除失败");
    }

    @Override
    public Result<T> doAccordingToDeleteManagementHours(int id) {
        if (workMapper.delManagementHoursById(id) > 0) {
            return Result.success("删除成功");
        }
        return Result.failure("删除失败");
    }

    /*
     * @Author wzy
     * @Description //TODO 通过时间查询个人管理工时信息
     * @Date 2021/12/15 15:50
     * @Param * @param: time
     * @param: pageNum
     * @param: pageSize
     * @return com.lzy.wzy.result.Result<com.github.pagehelper.PageInfo<com.lzy.wzy.vo.ManageWorkingTimeVo>>
     **/
    @Override
    public Result<PageInfo<ManageWorkingTimeVo>> doGetCurMonthManageWorkingHoursInfo(String time, int pageNum, String val) {
        PageHelper.startPage(pageNum, 10);
        String[] split = time.split("-");
        String jobNumber;
        if (StringUtils.isNotBlank(val)) {
            jobNumber=val;
        }else {
            jobNumber= (String) SecurityContextHolder.getContext().getAuthentication().getCredentials();
        }
        List<ManageWorkingTimeVo> personalManageWorkingHoursInfoByTime = workMapper.getPersonalManageWorkingHoursInfoByTime(Integer.parseInt(split[0]), Integer.parseInt(split[1]),jobNumber);
        PageInfo<ManageWorkingTimeVo> pageInfo = new PageInfo<>(personalManageWorkingHoursInfoByTime);
        return Result.success(pageInfo);
    }


    @Override
    public Result<List<TicketVo>> doGetSearchInfo(String val) {
        List<TicketVo> ticketVos;
        val=val+"%";
        if (PatternUtils.checkWorkOrderNumber(val.replace("%",""))){
            ticketVos=workMapper.searchWorkOrderNumber(val);
        }else if (PatternUtils.verifyCodePrefix(val)){
            ticketVos=workMapper.searchProductCode(val);
        }else {
            ticketVos=workMapper.searchOrderNumber(val);
        }
        return Result.success(ticketVos);
    }

    @Override
    public Result<Set<String>> doGetVideoLink() {
        return Result.success(userMapper.getAllVideo());
    }

    private void exportManageHours(Map<String, List<ManageWorkingTimeVo>> data, String title, HttpServletResponse response) throws IOException {
        //创建poi导出数据对象
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
        //创建sheet页
        SXSSFSheet sheet = sxssfWorkbook.createSheet(title);
        int firstRow = 0;
        int lastRow = 0;
        int firstCol = 0;
        int lastCol = 3;
        SXSSFRow sheetRow = sheet.createRow(firstRow);
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
        sheetRow.createCell(firstCol).setCellValue("项目编号");
        sheetRow.createCell(4).setCellValue("项目名称");
        sheetRow.createCell(5).setCellValue("正班工时");
        sheetRow.createCell(6).setCellValue("加班工时");
        sheetRow.createCell(7).setCellValue("总计工时");
        sheetRow.createCell(8).setCellValue("备注");
        sheetRow.createCell(9).setCellValue("署名");
        sheetRow.createCell(10).setCellValue("工号");
        sheetRow.createCell(11).setCellValue("日期");
        CellRangeAddress address;
        SXSSFRow row = null;
        for (Map.Entry<String, List<ManageWorkingTimeVo>> entry : data.entrySet()) {
            firstRow = lastRow + 1;
            lastRow += entry.getValue().size();
            address = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
            sheet.addMergedRegion(address);
            row = sheet.createRow(firstRow);
            row.createCell(firstCol).setCellValue(entry.getKey());
            exportManageHoursPack(sheet, entry.getValue(), row, firstRow, lastCol);
            lastRow = address.getLastRow() + 1;
        }

        if (row != null) {
            lastRow = sheet.getLastRowNum() + 4;
            row = sheet.createRow(lastRow);
            row.createCell(1).setCellValue("项目编号");
            row.createCell(2).setCellValue("项目名称");
            row.createCell(3).setCellValue("正班工时总计");
            row.createCell(4).setCellValue("加班工时总计");
            row.createCell(5).setCellValue("总计工时");
            for (Map.Entry<String, List<ManageWorkingTimeVo>> entry : data.entrySet()) {
                row = sheet.createRow(++lastRow);
                row.createCell(1).setCellValue(entry.getKey());
                row.createCell(2).setCellValue(entry.getValue().get(0).getProjectName());
                row.createCell(3).setCellValue(entry.getValue().stream().mapToDouble(ManageWorkingTimeVo::getWorkingTime).sum());
                row.createCell(4).setCellValue(entry.getValue().stream().mapToDouble(ManageWorkingTimeVo::getOverTime).sum());
                row.createCell(5).setCellValue(entry.getValue().stream().mapToDouble(ManageWorkingTimeVo::getTotalWorkingTime).sum());
            }
        }


        response.setCharacterEncoding("UTF-8");
        //  response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        response.setContentType("application/vnd.ms-excel");
        //一定要设置成xlsx格式
        //response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename + ".xlsx", "UTF-8"));
        //创建一个输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //写入数据
        sxssfWorkbook.write(outputStream);
        outputStream.flush();
        // 关闭
        outputStream.close();
        sxssfWorkbook.close();
    }

    private void exportManageHoursPack(SXSSFSheet sheet, List<ManageWorkingTimeVo> list, SXSSFRow curRow, int firstRow, int firstCol) {
        SXSSFRow row;
        int temp;
        for (ManageWorkingTimeVo workingTimeVo : list) {
            temp = firstCol + 1;
            if (firstRow == curRow.getRowNum()) {
                row = curRow;
            } else {
                row = sheet.createRow(firstRow);
            }
            row.createCell(temp).setCellValue(workingTimeVo.getProjectName());
            row.createCell(++temp).setCellValue(workingTimeVo.getWorkingTime());
            row.createCell(++temp).setCellValue(workingTimeVo.getOverTime());
            row.createCell(++temp).setCellValue(workingTimeVo.getTotalWorkingTime());
            row.createCell(++temp).setCellValue(workingTimeVo.getRemarks());
            row.createCell(++temp).setCellValue(workingTimeVo.getName());
            row.createCell(++temp).setCellValue(workingTimeVo.getJobNumber());
            row.createCell(++temp).setCellValue(workingTimeVo.getRecordDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            firstRow++;
        }
    }

    private void exportProjectHours(Map<String, List<OutOfHoursStatisticsVo>> data, String title, HttpServletResponse response) throws IOException {
        //创建poi导出数据对象
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
        SXSSFSheet sheet = sxssfWorkbook.createSheet(title);
        int firstRow = 0;
        int lastRow = 0;
        int firstCol = 0;
        int lastCol = 3;
        SXSSFRow sheetRow = sheet.createRow(firstRow);
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
        sheetRow.createCell(firstCol).setCellValue("项目编号");
        sheetRow.createCell(4).setCellValue("项目名称");
        sheetRow.createCell(5).setCellValue("作业人数");
        sheetRow.createCell(6).setCellValue("正班工时");
        sheetRow.createCell(7).setCellValue("加班工时");
        sheetRow.createCell(8).setCellValue("总计工时");
        sheetRow.createCell(9).setCellValue("备注");
        sheetRow.createCell(10).setCellValue("署名");
        sheetRow.createCell(11).setCellValue("日期");
        CellRangeAddress address;
        SXSSFRow row = null;
        for (Map.Entry<String, List<OutOfHoursStatisticsVo>> entry : data.entrySet()) {
            firstRow = lastRow + 1;
            lastRow += entry.getValue().size();
            address = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
            sheet.addMergedRegion(address);
            row = sheet.createRow(firstRow);
            row.createCell(firstCol).setCellValue(entry.getKey());
            exportProjectHoursPack(sheet, entry.getValue(), row, firstRow, lastCol);
            lastRow = address.getLastRow() + 1;
        }

        if (row != null) {
            lastRow = sheet.getLastRowNum() + 4;
            row = sheet.createRow(lastRow);
            row.createCell(1).setCellValue("项目编号");
            row.createCell(2).setCellValue("项目名称");
            row.createCell(3).setCellValue("正班工时总计");
            row.createCell(4).setCellValue("加班工时总计");
            row.createCell(5).setCellValue("总计工时");
            row.createCell(6).setCellValue("合计");
            double sum = 0;
            double temp;
            for (Map.Entry<String, List<OutOfHoursStatisticsVo>> entry : data.entrySet()) {
                row = sheet.createRow(++lastRow);
                row.createCell(1).setCellValue(entry.getKey());
                row.createCell(2).setCellValue(entry.getValue().get(0).getProjectName());
                row.createCell(3).setCellValue(entry.getValue().stream().mapToDouble(OutOfHoursStatisticsVo::getWorkingTime).sum());
                row.createCell(4).setCellValue(entry.getValue().stream().mapToDouble(OutOfHoursStatisticsVo::getOverTime).sum());
                temp = entry.getValue().stream().mapToDouble(OutOfHoursStatisticsVo::getTotalWorkingTime).sum();
                row.createCell(5).setCellValue(temp);
                sum += temp;
            }
            row = sheet.createRow(++lastRow);
            row.createCell(6).setCellValue(sum);
        }


        response.setCharacterEncoding("UTF-8");
        //  response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        response.setContentType("application/vnd.ms-excel");
        //一定要设置成xlsx格式
        //response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename + ".xlsx", "UTF-8"));
        //创建一个输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //写入数据
        sxssfWorkbook.write(outputStream);
        outputStream.flush();
        // 关闭
        outputStream.close();
        sxssfWorkbook.close();
    }

    private void exportProjectHoursPack(SXSSFSheet sheet, List<OutOfHoursStatisticsVo> list, SXSSFRow curRow, int firstRow, int firstCol) {
        SXSSFRow row;
        int temp;
        for (OutOfHoursStatisticsVo statisticsVo : list) {
            temp = firstCol+1;
            if (firstRow == curRow.getRowNum()) {
                row = curRow;
            } else {
                row = sheet.createRow(firstRow);
            }
            row.createCell(temp).setCellValue(statisticsVo.getProjectName());
            row.createCell(++temp).setCellValue(statisticsVo.getNumberOfOperations());
            row.createCell(++temp).setCellValue(statisticsVo.getWorkingTime());
            row.createCell(++temp).setCellValue(statisticsVo.getOverTime());
            row.createCell(++temp).setCellValue(statisticsVo.getTotalWorkingTime());
            row.createCell(++temp).setCellValue(statisticsVo.getRemarks());
            row.createCell(++temp).setCellValue(statisticsVo.getName());
            row.createCell(++temp).setCellValue(statisticsVo.getProjectDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            firstRow++;
        }
    }


    private void exportProductionHours(Map<String, List<WorkingHoursVo>> data, String title, HttpServletResponse response) throws IOException {
        //创建poi导出数据对象
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
        CellStyle style = sxssfWorkbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        //创建sheet页
        SXSSFSheet sheet = sxssfWorkbook.createSheet(title);
        int firstRow = 0;
        int lastRow = 0;
        int firstCol = 0;
        int lastCol = 3;
        SXSSFRow sheetRow = sheet.createRow(firstRow);
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
        sheetRow.createCell(firstCol).setCellValue("工单号");
        sheetRow.createCell(4).setCellValue("实际产出");
        sheetRow.createCell(5).setCellValue("正班工时");
        sheetRow.createCell(6).setCellValue("加班工时");
        sheetRow.createCell(7).setCellValue("总计工时");
        sheetRow.createCell(8).setCellValue("备注");
        sheetRow.createCell(9).setCellValue("署名");
        sheetRow.createCell(10).setCellValue("日期");
        CellRangeAddress address;
        SXSSFRow row = null;
        int rowNum;
        for (Map.Entry<String, List<WorkingHoursVo>> entry : data.entrySet()) {
            firstRow = lastRow + 1;
            lastRow += entry.getValue().size();
            address = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
            sheet.addMergedRegion(address);
            row = sheet.createRow(firstRow);
            row.createCell(firstCol).setCellValue(entry.getKey());
            productionHoursReportPack(sheet, entry.getValue(), row, firstRow, lastCol);
            rowNum = row.getRowNum() + entry.getValue().size();
            row = sheet.createRow(rowNum);
            row.createCell(0).setCellValue("产品编码:");
            row.createCell(1).setCellValue(entry.getValue().get(0).getProductCode());
            row.createCell(3).setCellValue("产品型号:");
            row.createCell(4).setCellValue(entry.getValue().get(0).getProductNumber());
            row.createCell(6).setCellValue("生产数量:");
            row.createCell(7).setCellValue(entry.getValue().get(0).getProductionQuantity());
            sheet.createRow(++rowNum).createCell(0).setCellValue("///////////////////////////////////////////////////////////////////////");
            lastRow = address.getLastRow() + 3;
        }

        if (row != null) {
            lastRow = sheet.getLastRowNum() + 4;
            row = sheet.createRow(lastRow);
            row.createCell(1).setCellValue("工单号");
            row.createCell(2).setCellValue("正班工时总计");
            row.createCell(3).setCellValue("加班工时总计");
            row.createCell(4).setCellValue("总计工时");
            row.createCell(5).setCellValue("合计");
            double sum = 0;
            double temp;
            for (Map.Entry<String, List<WorkingHoursVo>> entry : data.entrySet()) {
                row = sheet.createRow(++lastRow);
                row.createCell(1).setCellValue(entry.getKey());
                row.createCell(2).setCellValue(entry.getValue().stream().mapToDouble(WorkingHoursVo::getWorkingHours).sum());
                row.createCell(3).setCellValue(entry.getValue().stream().mapToDouble(WorkingHoursVo::getOverTime).sum());
                temp = entry.getValue().stream().mapToDouble(WorkingHoursVo::getTotalWorkingHours).sum();
                sum += temp;
                row.createCell(4).setCellValue(temp);
            }
            row = sheet.createRow(++lastRow);
            row.createCell(5).setCellValue(sum);
        }

        response.setCharacterEncoding("UTF-8");
        //  response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        response.setContentType("application/vnd.ms-excel");
        //一定要设置成xlsx格式
        //response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename + ".xlsx", "UTF-8"));
        //创建一个输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //写入数据
        sxssfWorkbook.write(outputStream);
        outputStream.flush();
        // 关闭
        outputStream.close();
        sxssfWorkbook.close();
    }

    private void productionHoursReportPack(SXSSFSheet sheet, List<WorkingHoursVo> list, SXSSFRow curRow, int firstRow, int firstCol) {
        SXSSFRow row;
        int temp;
        for (WorkingHoursVo workingHoursVo : list) {
            temp = firstCol + 1;
            if (firstRow == curRow.getRowNum()) {
                row = curRow;
            } else {
                row = sheet.createRow(firstRow);
            }
            row.createCell(temp).setCellValue(workingHoursVo.getActualOutput());
            row.createCell(++temp).setCellValue(workingHoursVo.getWorkingHours());
            row.createCell(++temp).setCellValue(workingHoursVo.getOverTime());
            row.createCell(++temp).setCellValue(workingHoursVo.getTotalWorkingHours());
            row.createCell(++temp).setCellValue(workingHoursVo.getRemarks());
            row.createCell(++temp).setCellValue(workingHoursVo.getName());
            row.createCell(++temp).setCellValue(workingHoursVo.getRecordDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
            firstRow++;
        }
    }

    private void export(String title, Map<String, List<ManageTimeVo>> data, Map<String, List<ManageTimeVo>> names, HttpServletResponse response) throws IOException {
        //创建poi导出数据对象
        SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook();
        CellStyle style = sxssfWorkbook.createCellStyle();
        style.setAlignment(HorizontalAlignment.CENTER);
        //创建sheet页
        SXSSFSheet sheet = sxssfWorkbook.createSheet(title);
        int firstRow = 0;
        int lastRow = 0;
        int firstCol = 0;
        int lastCol = 3;
        SXSSFRow sheetRow = sheet.createRow(firstRow);
        sheet.addMergedRegion(new CellRangeAddress(firstRow, lastRow, firstCol, lastCol));
        sheetRow.createCell(firstCol).setCellValue("项目名称");
        sheetRow.createCell(4).setCellValue("姓名");
        sheetRow.createCell(5).setCellValue("正班工时");
        sheetRow.createCell(6).setCellValue("加班工时");
        sheetRow.createCell(7).setCellValue("个人总计工时");
        CellRangeAddress address;
        SXSSFRow row = null;
        for (Map.Entry<String, List<ManageTimeVo>> entry : data.entrySet()) {
            firstRow = lastRow + 1;
            lastRow += entry.getValue().size();
            address = new CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
            sheet.addMergedRegion(address);
            row = sheet.createRow(firstRow);
            row.createCell(firstCol).setCellValue(entry.getKey());
            reportPack(sheet, entry.getValue(), row, firstRow, lastCol);
            lastRow = address.getLastRow();
        }
        if (row != null) {
            int rowNum = sheet.getLastRowNum();
            ++rowNum;
            row = sheet.createRow(++rowNum);
            row.createCell(0).setCellValue("姓名");
            row.createCell(1).setCellValue("工时");
            for (Map.Entry<String, List<ManageTimeVo>> entry : names.entrySet()) {
                row = sheet.createRow(++rowNum);
                row.createCell(0).setCellValue(entry.getKey());
                row.createCell(1).setCellValue(entry.getValue().stream().mapToDouble(ManageTimeVo::getTotalHours).sum());
            }

            rowNum = rowNum + 2;
            row = sheet.createRow(rowNum);
            row.createCell(0).setCellValue("项目名称");
            row.createCell(1).setCellValue("项目管理总用工时");
            row.createCell(2).setCellValue("合计");
            double total = 0;
            double sum;
            for (Map.Entry<String, List<ManageTimeVo>> entry : data.entrySet()) {
                row = sheet.createRow(++rowNum);
                row.createCell(0).setCellValue(entry.getKey());
                sum = entry.getValue().stream().mapToDouble(ManageTimeVo::getTotalHours).sum();
                total += sum;
                row.createCell(1).setCellValue(sum);
            }
            row = sheet.createRow(++rowNum);
            row.createCell(2).setCellValue(total);
        }
        // 设置头信息
        response.setCharacterEncoding("UTF-8");
        //  response.setHeader("Set-Cookie", "fileDownload=true; path=/");
        response.setContentType("application/vnd.ms-excel");
        //一定要设置成xlsx格式
        //response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename + ".xlsx", "UTF-8"));
        //创建一个输出流
        ServletOutputStream outputStream = response.getOutputStream();
        //写入数据
        sxssfWorkbook.write(outputStream);
        outputStream.flush();
        // 关闭
        outputStream.close();
        sxssfWorkbook.close();
    }

    private void reportPack(SXSSFSheet sheet, List<ManageTimeVo> list, SXSSFRow curRow, int firstRow, int firstCol) {
        SXSSFRow row;
        int temp;
        for (ManageTimeVo timeVo : list) {
            temp = firstCol + 1;
            if (firstRow == curRow.getRowNum()) {
                row = curRow;
            } else {
                row = sheet.createRow(firstRow);
            }
            row.createCell(temp).setCellValue(timeVo.getName());
            row.createCell(++temp).setCellValue(timeVo.getTotalWorkingHours());
            row.createCell(++temp).setCellValue(timeVo.getTotalOverTime());
            row.createCell(++temp).setCellValue(timeVo.getTotalHours());
            firstRow++;
        }
//        if (row != null) {
//            double total = list.stream().mapToDouble(ManageTimeVo::getTotalHours).sum();
//            row.createCell(8).setCellValue(total);
//        }
    }

    private void packSvo(List<StatHoursVo> statHoursVos, String title, String suf, StatisticsHoursResultVo resultVo, boolean idf) {
        List<String> list1 = new ArrayList<>();
        List<Float> list2 = new ArrayList<>();
        List<Float> list3 = new ArrayList<>();
        List<Float> list4 = new ArrayList<>();
        for (StatHoursVo statHoursVo : statHoursVos) {
            if (statHoursVo == null)
                return;
            if (idf) {
                list1.add(statHoursVo.getHours().getDayOfMonth() + suf);
            } else {
                list1.add(statHoursVo.getCMonth() + suf);
            }
            list2.add(statHoursVo.getTotalWorkingHours());
            list3.add(statHoursVo.getTotalOverTime());
            list4.add(statHoursVo.getTotalHours());
        }
        resultVo.setTitle(title);
        resultVo.setTimeList(list1);
        resultVo.setWorkingHoursList(list2);
        resultVo.setOverTimeList(list3);
        resultVo.setTotalHoursList(list4);
    }

    //    @Override
//    public Result<HoursStaticsVo> doAnnualStatisticsOfProductionHoursByNumber(int workOrderNumber) {
//        return Result(ResponseCode.SUCCESS.getCode(), ResponseCode.SUCCESS.getMsg(), workMapper.queryProductHoursByWorkOrderNumber(workOrderNumber));
//    }

    private List<String> getTheAbnormalTicketNumber(MyUsernamePasswordToken token) {
        List<String> list = token.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(Collectors.toList());
        List<String> resultList = new ArrayList<>();

        if (list.contains(MyConstant.ApproveGroup.quality)) {
            resultList = workMapper.getWorkOrderNumberByProcessingStatusAndIdentifier(MyConstant.ReportStatus.PENDING, 0);
            if (resultList.isEmpty()
                    && list.contains(MyConstant.ApproveGroup.confirmG)) {
                resultList = workMapper.getWorkOrderNumberByProcessingStatus(MyConstant.ReportStatus.TOBE_CONFIRMED);
            }
            if (Arrays.stream(MyConstant.ApproveGroup.craft).anyMatch(list::contains)) {
                List<String> list2 = workMapper.getWorkOrderNumberByProcessingStatusAndIdentifier(MyConstant.ReportStatus.PENDING, 1);
                resultList.addAll(list2);
            }
        } else if (Arrays.stream(MyConstant.ApproveGroup.craft).anyMatch(list::contains)) {
            resultList = workMapper.getWorkOrderNumberByProcessingStatusAndIdentifier(MyConstant.ReportStatus.PENDING, 1);
        } else if (list.contains(MyConstant.ApproveGroup.executorG)) {
            resultList = workMapper.getWorkOrderNumberByProcessingStatus(MyConstant.ReportStatus.PENDING_EXECUTE).stream().distinct().collect(Collectors.toList());
        } else if (list.contains(MyConstant.ApproveGroup.confirmG)) {
            resultList = workMapper.getWorkOrderNumberByProcessingStatus(MyConstant.ReportStatus.TOBE_CONFIRMED).stream().distinct().collect(Collectors.toList());
        }

//        if (Arrays.stream(MyConstant.ApproveGroup.craft).anyMatch(list::contains)) {
//            resultList = workMapper.getWorkOrderNumberByProcessingStatusAndIdentifier(MyConstant.ReportStatus.PENDING, 1);
//            return resultList;
//        }
//        if (Arrays.stream(MyConstant.ApproveGroup.pendingG).anyMatch(list::contains)) {
//            List<String> resultList;
//            resultList = workMapper.getWorkOrderNumberByProcessingStatus(MyConstant.ReportStatus.PENDING);
//            if (resultList.isEmpty()
//                    && list.contains(MyConstant.ApproveGroup.confirmG)) {
//                resultList = workMapper.getWorkOrderNumberByProcessingStatus(MyConstant.ReportStatus.TOBE_CONFIRMED);
//            }
//            return resultList.stream().distinct().collect(Collectors.toList());
//        }
//        if (list.contains(MyConstant.ApproveGroup.executorG)) {
//            return workMapper.getWorkOrderNumberByProcessingStatus(MyConstant.ReportStatus.PENDING_EXECUTE).stream().distinct().collect(Collectors.toList());
//        }
//        if (list.contains(MyConstant.ApproveGroup.confirmG)) {
//            return workMapper.getWorkOrderNumberByProcessingStatus(MyConstant.ReportStatus.TOBE_CONFIRMED).stream().distinct().collect(Collectors.toList());
//        }
        return resultList;
    }

    public List<EchartsVo> getWorkOrderStatistics() {
        List<String> list = workMapper.getAllWorkOrderStatus();

        int total = list.size();
        Map<String, List<String>> collect = list.stream().collect(Collectors.groupingBy(l -> l));

        Map<String, List<String>> reMap = new LinkedHashMap<>();
        List<String> temp = new ArrayList<>();
        reMap.put(MyConstant.WorkOrderStatus.RELEASE, temp);
        reMap.put(MyConstant.WorkOrderStatus.InSystem, temp);
        reMap.put(MyConstant.WorkOrderStatus.FINISHED, temp);
        reMap.put(MyConstant.WorkOrderStatus.CASECLOSE, temp);
        String key;
        for (Map.Entry<String, List<String>> entry : collect.entrySet()) {
            key = entry.getKey();
            reMap.put(key, entry.getValue());
        }
        collect.clear();
        String result;
        float val;
        List<EchartsVo> reList = new ArrayList<>();
        EchartsVo echartsVo;
        int size;
        BigDecimal re1;
        BigDecimal re2 = new BigDecimal(Float.toString(100));
        for (Map.Entry<String, List<String>> entry : reMap.entrySet()) {
            echartsVo = new EchartsVo();
            size = entry.getValue().size();
            if (size > 0) {
                result = String.format("%.3f", size / (float) total);
                re1 = new BigDecimal(result);
                val = re1.multiply(re2).floatValue();
            } else {
                val = size;
            }
            echartsVo.setValue(val);
            echartsVo.setName(entry.getKey() + "：" + val + "% (" + size + ")");
            reList.add(echartsVo);
        }
        return reList;
    }

    private YearMonthVo getTimeVisit() {
        LocalDate first = workMapper.getFirstRecord();
        if (first != null) {
            YearMonthVo vo = new YearMonthVo();
            LocalDate last = workMapper.getLastRecord();
            int firstYear = first.getYear();
            int lastYear = last.getYear();
            List<Integer> year = new ArrayList<>();
            for (int i = firstYear; i <= lastYear; i++) {
                year.add(i);
            }
            vo.setYear(year);
            int firstMonth = first.getMonthValue();
            int lastMonth = last.getMonthValue();
            int max = Math.max(LocalDate.now().getMonthValue(), lastMonth);
            List<Integer> month = new ArrayList<>();
            if (firstYear == lastYear) {
                for (int i = firstMonth; i <= max; i++) {
                    month.add(i);
                }
            } else {
                for (int i = 1; i <= 12; i++) {
                    month.add(i);
                }
            }
            vo.setMonth(month);
            LocalDate now = LocalDate.now();
            vo.setDefaultYear(now.getYear());
            vo.setDefaultMonth(now.getMonthValue());
            List<String> productCode = workMapper.getAllProductCode();

            if (!productCode.isEmpty()) {
                vo.setDefaultProductCode(productCode.get(0));
            }
            int day = LocalDate.now().with(TemporalAdjusters.lastDayOfMonth()).getDayOfMonth();

            List<Integer> days = new ArrayList<>();

            for (int i = 1; i <= day; i++) {
                days.add(i);
            }
            vo.setProductCode(productCode);
            vo.setDays(days);
            vo.setDefaultDay(now.getDayOfMonth());
            return vo;
        }
        return null;
    }

    public List<ApprovalResultsVo> getApprovalResult(String userId) {
        List<ApprovalResultsVo> results = userMapper.getApprovalResults(userId);
        for (ApprovalResultsVo resultsVo : results) {
            if (null == resultsVo.getExecutor()) {
                resultsVo.setExecutor("未审核");
            }
        }
        return results;
    }
}
